﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Coolite.Ext.Web;
using Newtonsoft.Json.Linq;
using Pap.Data;
using Pap.Services.WorkflowEngine;
using Pap.Web.Modules.Loan.ViewModel;
using Pap.Web.Utils;
using Utils;
using Utils.UIPermission;

namespace Pap.Web.Modules.Loan.Views
{

    /// <summary>
    /// 
    /// </summary>
    public partial class BoardMom : BasePage<BoardMomViewModel>, IPermittedPage
    {
        /// <summary>
        /// Handles the Load event of the Page, and get all boards .
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Ext.IsAjaxRequest && !Page.IsPostBack)
            {
                RefreshBoards();
                storeBoardPaymentMethods.DataSource = this.ViewModel.GetPaymentMethods();
                storeBoardPaymentMethods.DataBind();

                var actionList = from a in this.ViewModel.GetAvailableActions()
                                 select new
                                 {
                                     DecisionID = Enums.ToString(a),
                                     DecisionName = Enums.ToString(a, GetLocalResourceObject("LanguageIndex").ToInt32())
                                 };
                storeDecisions.DataSource = actionList;
                storeDecisions.DataBind();
            }
        }

        /// <summary>
        /// Refreshes the boards.
        /// </summary>
        private void RefreshBoards()
        {
            IEnumerable boards = this.ViewModel.GetNewBoards();
            if (boards != null)
            {
                storeBoards.DataSource = boards;
                storeBoards.DataBind();

                RowSelectionModel selectionModel = grvBoards.SelectionModel.Primary as RowSelectionModel;
                selectionModel.ClearSelections();

                storeBoardLoans.RemoveAll();
            }
        }

        /// <summary>
        /// Handles the Selected event of the Boards gridview and get all its loans.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void Board_Selected(object sender, AjaxEventArgs e)
        {
            RowSelectionModel selectionModel = grvBoards.SelectionModel.Primary as RowSelectionModel;
            if (selectionModel.SelectedRows.Count > 0)
            {
                Guid boardId = new Guid(selectionModel.SelectedRows[0].RecordID);


                IBoard board = this.ViewModel.GetBoardByID(boardId);
                ucAttachment.SetImages(this.ViewModel.GetBoardAttachements(boardId));
                ucAttachment.ExtraLabel = string.Format("{0}, {1}, {2}, ", board.CommitteeObj.CommitteeName,
                                                        board.BoardDate.ToString("dd/MM/yyyy"), board.BoardNumber);
                //if (board.BoardLoans.Count() > 0)
                //{
                //    var firstBoardLoan = board.BoardLoans.First().LoanObj;
                //    txtBoardLoanAmount.MinValue = firstBoardLoan.ProjectStage.From;
                //    txtBoardLoanAmount.MaxValue = firstBoardLoan.ProjectStage.To;
                //    txtBoardLoanAmount.Text = "18";                    
                //}
                if (e.ExtraParams["Editable"] != null)
                {
                    if (Convert.ToBoolean(e.ExtraParams["Editable"]))
                    {
                        grvBoardLoan.Disabled = true;
                        ucAttachment.Disabled = true;
                        btnSubmit.Disabled = true;
                    }
                    else
                    {
                        grvBoardLoan.Disabled = false;
                        ucAttachment.Disabled = false;
                        btnSubmit.Disabled = false;
                    }
                }
                storeBoardLoans.DataSource = this.ViewModel.GetBoardLoans(boardId);
                storeBoardLoans.DataBind();
            }
            else storeBoardLoans.RemoveAll();
        }

        /// <summary>
        /// Gets the max.
        /// </summary>
        /// <returns></returns>
        public double GetMax()
        {
            return 2000;
        }

        /// <summary>
        /// Handles the Command event of the GrvBoards control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void GrvBoards_Command(object sender, AjaxEventArgs e)
        {
            if (e.ExtraParams["GridCommand"] != null)
            {
                if (e.ExtraParams["GridCommand"].Equals("EditColumn"))
                {
                    RowSelectionModel selectionModel = grvBoards.SelectionModel.Primary as RowSelectionModel;
                    Guid boardId = new Guid(selectionModel.SelectedRows[0].RecordID);
                    this.RedirectFromThisPage("CreateBoard", new string[] { "BoardID=" + boardId.ToString() });
                }
            }
        }

        /// <summary>
        /// Handles the Clicked event of the BtnSave button that take a decision for loans discussed in a board.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void BtnSubmit_Clicked(object sender, AjaxEventArgs e)
        {
            try
            {
                RowSelectionModel selectionModel = grvBoards.SelectionModel.Primary as RowSelectionModel;
                if (selectionModel.SelectedRows.Count > 0)
                {
                    Guid boardID = (new Guid(selectionModel.SelectedRows[0].RecordID));
                    string boardNotes = null;
                    string jason = e.ExtraParams["grvBoards"];
                    JArray jarrChanges = (JArray)JSON.Deserialize(jason);
                    boardNotes = jarrChanges[0]["StatusNotes"].ToString().Trim('"');

                    jason = e.ExtraParams["grvBoardLoanGrid"];
                    jarrChanges = (JArray)JSON.Deserialize(jason);
                    Dictionary<string, int> actionTypeDic = Enums.ToNameKeyPaires(typeof(ActionTypes));

                    var LoanDecisions = (from item in jarrChanges
                                         where (!string.IsNullOrEmpty(item["DecisionID"].ToString().Trim('"')))

                                         select new
                                         {
                                             LoanID = item["LoanID"].ToString().Trim('"').ToGuid(),
                                             Decision = (ActionTypes)actionTypeDic[item["DecisionID"].ToString().Trim('"')],
                                             BoardLoanAmount = item["BoardLoanAmount"].ToString().Trim('"'),
                                             BoardPaymentPeriod = item["BoardPaymentPeriod"].ToString().Trim('"'),
                                             BoardpaymentMethod = item["BoardpaymentMethodID"].ToString().Trim('"'),
                                             StatusNotes = item["StatusNotes"].ToString().Trim('"'),
                                             LoanNumber = item["LoanNumber"].ToString().Trim('"')
                                         });

                    List<string> notValidAmountErrors = new List<string>();

                    if (LoanDecisions.Count() == jarrChanges.Count)
                    {
                        Dictionary<BoardLoanData, ActionTypes> loanDecision = new Dictionary<BoardLoanData, ActionTypes>();
                        foreach (var loan in LoanDecisions)
                        {
                            var loanProjectStage = this.GetLoanBy(loan.LoanID).ProjectStage;
                            if (double.Parse(loan.BoardLoanAmount) < loanProjectStage.From || double.Parse(loan.BoardLoanAmount) > loanProjectStage.To)
                            {
                                notValidAmountErrors.Add(loan.LoanNumber);
                            }
                            else
                            {
                                loanDecision.Add(
                                   new BoardLoanData
                                   {
                                       LoanID = loan.LoanID,
                                       BoardLoanAmount = Convert.ToDouble(loan.BoardLoanAmount),
                                       BoardpaymentMethod = loan.BoardpaymentMethod.ToGuid(),
                                       BoardPaymentPeriod = Convert.ToInt32(loan.BoardPaymentPeriod),
                                       StatusNotes = loan.StatusNotes,
                                   }, loan.Decision);
                            }
                        }

                        if (notValidAmountErrors.Count > 0)
                        {
                            string errorloans = string.Join(" , ", notValidAmountErrors.ToArray());
                            Ext.Msg.Configure(new MessageBox.Config
                            {
                                Title = GetLocalResourceObject("MBError").ToString(),
                                Message = GetLocalResourceObject("MBErrorLoans").ToString() + " " + errorloans,
                                Buttons = MessageBox.Button.OK,
                                Icon = MessageBox.Icon.ERROR
                            }).Show();
                        }
                        else
                        {
                            this.ViewModel.SubmitBoard(boardID, boardNotes, ucAttachment.GetInsertedIDs(),
                                                       ucAttachment.GetDeletedIDs(), loanDecision);
                            RefreshBoards();
                        }
                    }
                    else
                    {
                        Ext.Msg.Configure(new MessageBox.Config
                        {
                            Icon = MessageBox.Icon.ERROR,
                            Title = GetLocalResourceObject("Error").ToString(),
                            Modal = true,
                            Message = GetLocalResourceObject("LoansNotSubmitted").ToString(),
                            Buttons = MessageBox.Button.OK
                        }).Show();
                    }
                }
                else
                {
                    Ext.Msg.Configure(new MessageBox.Config
                    {
                        Icon = MessageBox.Icon.ERROR,
                        Title = GetLocalResourceObject("Error").ToString(),
                        Modal = true,
                        Message = GetLocalResourceObject("NoSelectedBoards").ToString(),
                        Buttons = MessageBox.Button.OK
                    }).Show();
                }
            }
            catch
            {

                Ext.Msg.Configure(new MessageBox.Config
                {
                    Icon = MessageBox.Icon.ERROR,
                    Title = GetLocalResourceObject("Error").ToString(),
                    Modal = true,
                    Message = GetLocalResourceObject("ErrorMsg").ToString(),
                    Buttons = MessageBox.Button.OK
                }).Show();
            }
        }

        /// <summary>
        /// Gets the loan by.
        /// </summary>
        /// <param name="loanID">The loan ID.</param>
        /// <returns></returns>
        private ICustomerLoan GetLoanBy(Guid loanID)
        {
            ICustomerLoan loan = this.ViewModel.GetLoanByID(loanID);
            return loan;
        }

        /// <summary>
        /// Handles the Clicked event of the BtnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void BtnSave_Clicked(object sender, AjaxEventArgs e)
        {
            try
            {
                RowSelectionModel selectionModel = grvBoards.SelectionModel.Primary as RowSelectionModel;
                if (selectionModel.SelectedRows.Count > 0)
                {
                    Guid boardID = (new Guid(selectionModel.SelectedRows[0].RecordID));
                    string jason = e.ExtraParams["grvBoardLoanGrid"];
                    JArray jarrChanges = (JArray)JSON.Deserialize(jason);

                    Dictionary<BoardLoanData, string> loanDecisions = new Dictionary<BoardLoanData, string>();

                    for (int i = 0; i < jarrChanges.Count; i++)
                    {
                        bool valid = true;
                        BoardLoanData boardLoanData = new BoardLoanData();

                        boardLoanData.LoanID = jarrChanges[i]["LoanID"].ToString().Trim('"').ToGuid();
                        boardLoanData.BoardpaymentMethod =
                            jarrChanges[i]["BoardpaymentMethodID"].ToString().Trim('"').ToGuid();
                        boardLoanData.StatusNotes = jarrChanges[i]["StatusNotes"].ToString().Trim('"');

                        if (!string.IsNullOrEmpty(jarrChanges[i]["BoardLoanAmount"].ToString()))
                            boardLoanData.BoardLoanAmount =
                                Convert.ToDouble(jarrChanges[i]["BoardLoanAmount"].ToString().Trim('"'));
                        else
                            valid = false;

                        if (!string.IsNullOrEmpty(jarrChanges[i]["BoardPaymentPeriod"].ToString()))
                            boardLoanData.BoardPaymentPeriod =
                                Convert.ToInt32(jarrChanges[i]["BoardPaymentPeriod"].ToString().Trim('"'));
                        else
                            valid = false;

                        if (valid && !string.IsNullOrEmpty(jarrChanges[i]["DecisionID"].ToString()))
                            loanDecisions.Add(boardLoanData, jarrChanges[i]["DecisionID"].ToString().Trim('"'));
                        else
                            loanDecisions.Add(boardLoanData, string.Empty);
                    }
                    if (loanDecisions.Count() > 0)
                    {
                        this.ViewModel.SaveBoard(boardID, ucAttachment.GetInsertedIDs(), ucAttachment.GetDeletedIDs(), loanDecisions);
                        this.RedirectToPreviousPage();
                    }
                }
                else
                {
                    Ext.Msg.Configure(new MessageBox.Config
                    {
                        Icon = MessageBox.Icon.ERROR,
                        Title = GetLocalResourceObject("Error").ToString(),
                        Modal = true,
                        Message = GetLocalResourceObject("NoSelectedBoards").ToString(),
                        Buttons = MessageBox.Button.OK
                    }).Show();

                }
            }
            catch
            {

                Ext.Msg.Configure(new MessageBox.Config
                {
                    Icon = MessageBox.Icon.ERROR,
                    Title = GetLocalResourceObject("Error").ToString(),
                    Modal = true,
                    Message = GetLocalResourceObject("ErrorMsg").ToString(),
                    Buttons = MessageBox.Button.OK
                }).Show();
            }

        }

        /// <summary>
        /// Handles the Clicked event of the BtnPrint control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void BtnPrint_Clicked(object sender, AjaxEventArgs e)
        {
            RowSelectionModel selectionModel = grvBoards.SelectionModel.Primary as RowSelectionModel;
            if (selectionModel.SelectedRows.Count > 0)
            {
                Guid boardID = (new Guid(selectionModel.SelectedRows[0].RecordID));
                if (e.ExtraParams["BoardMomLoansGrid"] != null)
                {
                    JArray json = JSON.Deserialize(e.ExtraParams["BoardMomLoansGrid"]) as JArray;


                    var boardMembersPrint = this.ViewModel.GetBoardMomMembers(boardID);
                    var boardloansPrint = GetBoardLoansView(json);

                    Session["boardMomMembersPrint"] = boardMembersPrint;
                    Session["boardMomloansPrint"] = boardloansPrint;

                    var boardObj = this.ViewModel.GetBoardByID(boardID);

                    wndBoardMomPrint.LoadContent("~/Loan.route/PrintBoardMom?BoardNumber=" + boardObj.BoardNumber.ToString());
                    wndBoardMomPrint.Show();
                }
            }
        }

        /// <summary>
        /// Gets the board loans view.
        /// </summary>
        /// <param name="json">The json.</param>
        /// <returns></returns>
        private object GetBoardLoansView(JArray json)
        {
            Dictionary<string, int> actionTypeDic = Enums.ToNameKeyPaires(typeof(ActionTypes));
            return (from item in json
                    select new
                    {
                        LoanNumber = item["LoanNumber"].ToString().Trim('"'),
                        CustomerName = item["CustomerName"].ToString().Trim('"'),
                        LoanType = item["LoanType"].ToString().Trim('"'),
                        LoanAmount = item["LoanAmount"].ToString().Trim('"'),
                        BoardLoanAmount = item["BoardLoanAmount"].ToString().Trim('"'),
                        Decision = item["DecisionID"].ToString().Trim('"').IsNullOrEmpty() ?
                        string.Empty :
                        Enums.ToString((ActionTypes)actionTypeDic[item["DecisionID"].ToString().Trim('"')], GetLocalResourceObject("LanguageIndex").ToInt32()),
                        Notes = item["StatusNotes"].ToString().Trim('"')
                    });
        }

        /// <summary>
        /// Handles the Clicked event of the BtnCancle button.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void BtnCancle_Clicked(object sender, AjaxEventArgs e)
        {
            this.RedirectToPreviousPage();
        }

        /// <summary>
        /// 
        /// </summary>
        public class BoardLoanData
        {
            /// <summary>
            /// Gets or sets the loan ID.
            /// </summary>
            /// <value>
            /// The loan ID.
            /// </value>
            public Guid LoanID { get; set; }
            /// <summary>
            /// Gets or sets the board loan amount.
            /// </summary>
            /// <value>
            /// The board loan amount.
            /// </value>
            public double? BoardLoanAmount { get; set; }
            /// <summary>
            /// Gets or sets the board payment period.
            /// </summary>
            /// <value>
            /// The board payment period.
            /// </value>
            public int? BoardPaymentPeriod { get; set; }
            /// <summary>
            /// Gets or sets the boardpayment method.
            /// </summary>
            /// <value>
            /// The boardpayment method.
            /// </value>
            public Guid BoardpaymentMethod { get; set; }
            /// <summary>
            /// Gets or sets the status notes.
            /// </summary>
            /// <value>
            /// The status notes.
            /// </value>
            public string StatusNotes { get; set; }
        }

        /// <summary>
        /// Ons the edit loan DES.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void onEditLoanDes(object sender, AjaxEventArgs e)
        {
            RowSelectionModel sm = grvBoardLoan.SelectionModel.Primary as RowSelectionModel;

            var actionList = from a in this.ViewModel.GetAvailableActions()
                             select new
                             {
                                 DecisionID = Enums.ToString(a),
                                 DecisionName = Enums.ToString(a, GetLocalResourceObject("LanguageIndex").ToInt32())
                             };
            if (sm.SelectedIndex == 0)
            {
                actionList = actionList.Where(aa => aa.DecisionID.ToGuid().Equals(Enums.ToString(ActionTypes.Refuse).ToGuid()));
            }
            storeDecisions.DataSource = actionList;
            storeDecisions.DataBind();

        }

        #region IPermittedPage Members

        /// <summary>
        /// Gets the name of the permission.
        /// </summary>
        /// <value>
        /// The name of the permission.
        /// </value>
        public string PermissionName
        {
            get { return "BoardMom"; }
        }

        #endregion
    }
}
